#include <QGroupBox>
#include <QGridLayout>
#include <QLabel>
#include <QStatusBar>

#include "swclientwidget.h"
#include "swserverwidget.h"
#include "swmainwindow.h"

SWMainWindow::SWMainWindow()
{
    createDisplay();

    setAttribute(Qt::WA_DeleteOnClose);
}

void SWMainWindow::createDisplay()
{
    QWidget *display = new QWidget;
    QVBoxLayout *displayLayout = new QVBoxLayout;

    QGridLayout *serverLayout = new QGridLayout;
    QGroupBox *serverBox = new QGroupBox(tr("Create New Server"));
    QLabel *serverPortLabel = new QLabel(tr("Port"));
            m_serverPortEdit = new QLineEdit;
    QPushButton *serverStart = new QPushButton(tr("Start"));

    serverLayout->addWidget(serverPortLabel,  0, 0);
    serverLayout->addWidget(m_serverPortEdit, 0, 1);
    serverLayout->addWidget(serverStart,      1, 0, 1, 2);
    connect(serverStart, SIGNAL(clicked(bool)),
            this, SLOT(serverStartClicked(bool)));
    serverBox->setLayout(serverLayout);


    QGridLayout *clientLayout = new QGridLayout;
    QGroupBox *clientBox = new QGroupBox(tr("Create New Client"));
    QLabel *clientAddrLabel = new QLabel(tr("Address"));
            m_clientAddrEdit = new QLineEdit;
    QLabel *clientPortLabel = new QLabel(tr("Port"));
            m_clientPortEdit = new QLineEdit;
    QPushButton *clientStart = new QPushButton(tr("Start"));
    connect(clientStart, SIGNAL(clicked(bool)),
            this, SLOT(clientStartClicked(bool)));

    clientLayout->addWidget(clientAddrLabel,  0, 0);
    clientLayout->addWidget(m_clientAddrEdit, 0, 1);
    clientLayout->addWidget(clientPortLabel,  1, 0);
    clientLayout->addWidget(m_clientPortEdit, 1, 1);
    clientLayout->addWidget(clientStart,      2, 0, 2, 2);
    clientBox->setLayout(clientLayout);


    displayLayout->addWidget(serverBox);
    displayLayout->addWidget(clientBox);
    display->setLayout(displayLayout);

    connect(m_serverPortEdit, SIGNAL(returnPressed()), this, SLOT(spoofServerClick()));
    connect(m_clientPortEdit, SIGNAL(returnPressed()), this, SLOT(spoofClientClick()));
    connect(m_clientAddrEdit, SIGNAL(returnPressed()), this, SLOT(spoofClientClick()));

    setCentralWidget(display);
    display->show();
}

int SWMainWindow::validatePort(QString portString)
{
    bool isValidPort;
    int portNumber = portString.toInt(&isValidPort, 10);

    if (isValidPort == 0 || portNumber <= 0 || portNumber > 65535)
        return 0;

    return portNumber;
}

void SWMainWindow::clientStartClicked(bool)
{
    int portNumber;
    QString clientAddr = m_clientAddrEdit->text();
    QString clientPort = m_clientPortEdit->text();

    portNumber = validatePort(clientPort);
    if (portNumber == 0) {
        this->statusBar()->showMessage(
                tr("Error: Invalid client port %1.\n").arg(clientPort), 3000);
        return;
    }

    SWClientWidget *cw = new SWClientWidget(clientAddr, portNumber);
    if (cw->isConnected()) {
        cw->show();
        this->statusBar()->clearMessage();
    }
    else {
        this->statusBar()->showMessage(
                tr("Error: Couldn't connect to host '%1' on port %2.\n")
                .arg(clientAddr)
                .arg(clientPort), 3000);
        delete cw;
    }
}

void SWMainWindow::spoofClientClick()
{
    clientStartClicked(true);
}

void SWMainWindow::serverStartClicked(bool)
{
    int portNumber;
    QString serverPort = m_serverPortEdit->text();

    portNumber = validatePort(serverPort);
    if (portNumber == 0) {
        this->statusBar()->showMessage(
                tr("Error: Invalid server port %1.\n").arg(serverPort), 3000);
        return;
    }

    SWServerWidget *sw = new SWServerWidget(portNumber);
    if (sw->isListening()) {
        sw->show();
        this->statusBar()->clearMessage();
    }
    else {
        this->statusBar()->showMessage(
                tr("Error: Couldn't start server on port %1.\n").arg(serverPort), 3000);
        delete sw;
    }
}

void SWMainWindow::spoofServerClick()
{
    serverStartClicked(true);
}
